package com.anyisn.anyflickr.shell.model
{
	import com.adobe.webapis.flickr.AuthPerm;
	import com.adobe.webapis.flickr.AuthResult;
	import com.adobe.webapis.flickr.events.FlickrResultEvent;
	
	import flash.net.SharedObject;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	
	import mx.controls.Alert;
	import mx.utils.ObjectUtil;
	
	import com.anyisn.anyflickr.shell.ShellFacade;
	import com.anyisn.flickr.as3.FlickrConstants;
	import com.anyisn.flickr.as3.patterns.proxy.FlickrServiceProxy;

	public class AuthProxy extends FlickrServiceProxy
	{
		public static const NAME:String = 'AuthProxy';
		
		public function AuthProxy(data:Object=null)
		{
			super(NAME, data);
		}
		
		public function startLoginSequence():void {
			var flickrCookie:SharedObject = SharedObject.getLocal("AnyFlickr");
			if(flickrCookie.data.auth_token) {
				service.addEventListener(FlickrResultEvent.AUTH_CHECK_TOKEN, checkTokenResponse);
				service.auth.checkToken(flickrCookie.data.auth_token);
			} else {
				service.addEventListener(FlickrResultEvent.AUTH_GET_FROB, getFrobResponse);
				service.auth.getFrob();
			}
		}
		
		public function processLogout():void {
			// Configure the service so it looks like the user
			// is logged out
			service.token = "";
			service.permission = AuthPerm.NONE;
			
			// Update the UI to reflect the user being logged out
			sendNotification(ShellFacade.LOGOUT_SUCCESS);
			
			// Clear the authentication cookie so we don't auto-login next time
			var flickrCookie:SharedObject = SharedObject.getLocal("AnyFlickr");
			flickrCookie.clear();
			
			// Display a note about authentication to the user
			Alert.show("The application instance now considers you to be"
				+ " logged out.  However, the application is still"
				+ " authenticated on flickr.com until you remove it from"
				+ " your 'Authentication list' at"
				+ " http://www.flickr.com/services/auth/list.gne",
				"Logout successful",
				Alert.OK );
		}
		
		private function checkTokenResponse(event:FlickrResultEvent):void {
			if (event.success) {
				// Re-use the login logic in getTokenResponse
				getTokenResponse(event);
			} else {
				var flickrCookie:SharedObject = SharedObject.getLocal("AnyFlickr");
				flickrCookie.clear();
				onFlickrError(event);
				sendNotification(ShellFacade.LOGIN_FAILED);
			}
		}
		
		private function getTokenResponse(event:FlickrResultEvent):void {
			if (event.success) {
				var authResult:AuthResult = AuthResult(event.data.auth);
				
				// dump the object internals for debugging
				trace(ObjectUtil.toString(authResult));
				
				// Assign the token and permission to the service so that
				// all calls that require authentication have their values
				// populated
				service.token = authResult.token;
				service.permission = authResult.perms;
				
				// Save the token in a shared object so that when the application
				// loads again we can re-authenticate automatically
				var flickrCookie:SharedObject = SharedObject.getLocal("AnyFlickr");
				flickrCookie.data.auth_token = service.token;
				flickrCookie.data.permission = service.permission;
				flickrCookie.flush();
				
				// Update the UI to show the currently logged in username
				sendNotification(ShellFacade.LOGIN_SUCCESS, authResult);
			} else {
				onFlickrError(event);
				sendNotification(ShellFacade.LOGIN_FAILED);
			}
		}
		
		private function getFrobResponse(event:FlickrResultEvent):void {
			if (event.success) {
				// Have the service construct a login url for us with the
				// authentication frob, and request the user that we'd like
				// to have DELETE access to their data
				frob = event.data.frob;
				var auth_url:String = service.getLoginURL(frob, AuthPerm.DELETE);
				
				// Open a new browser window to authenticate the user
				// and grant our application permission
				navigateToURL(new URLRequest(auth_url), "_blank");
									
				// Show the alert saying  they need to authenticate on the 
				// flickr site.  when the alert closes, we need to get the 
				// token then to get their logged-in status
				Alert.show("This application requires that you authenticate"
							+ " on Flickr.com before proceeding.  Please log in"
							+ " to Flickr in the separate browser window that"
							+ " opened.  After you have successfully logged in,"
							+ " press 'OK' below to continue",
							"Authentication Required",
							Alert.OK | Alert.CANCEL,
							null,
							onCloseAuthWindow);
							
			} else {
				onFlickrError(event);
				sendNotification(ShellFacade.LOGIN_FAILED);
			}
		}
		
		private function onCloseAuthWindow(event:*):void {
			// Only process if they pressed OK
			if (event.detail == Alert.OK) {
				// Get their authentication token, and call getTokenResponse
				// when it's available
				service.addEventListener(FlickrResultEvent.AUTH_GET_TOKEN, getTokenResponse);
				service.auth.getToken(frob);
			}
		}

		private var frob:String;
	}
}